package com.dragon.hibernate.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;

import com.dragon.hibernate.dao.IDao;

public class Dao implements IDao {

	private static final Logger logger = LogManager.getLogger(Dao.class.getName());
	@Autowired
	@Qualifier("sessionFactory")
	protected SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public Dao() {

	}

	// @Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}



	public Session getSession() {
		// 事务必须是开启的，否则获取不到
		return sessionFactory.getCurrentSession();
	}


	@Override
	@SuppressWarnings("unchecked")
	public Object get(Serializable id, Class entityClass) {
		Assert.notNull(id, "id is required");
		return getSession().get(entityClass, id);
	}

	
	@Override
	@SuppressWarnings("unchecked")
	public Object load(Serializable id, Class entityClass) {
		Assert.notNull(id, "id is required");
		return getSession().load(entityClass, id);
	}

	
	@Override
	@SuppressWarnings("unchecked")
	public List get(Serializable[] ids, Class entityClass) {
		Assert.notEmpty(ids, "ids must not be empty");
		String hql = "from " + entityClass.getName() + " as model where model.id in(:ids)";
		return getSession().createQuery(hql).setParameterList("ids", ids).list();
	}

	
	@Override
	@SuppressWarnings("unchecked")
	public Object get(String propertyName, Object value, Class entityClass) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		String hql = "from " + entityClass.getName() + " as model where model." + propertyName + " = ?";
		return getSession().createQuery(hql).setParameter(0, value).uniqueResult();
	}


	@Override
	@SuppressWarnings("unchecked")
	public List getList(String propertyName, Object value, Class entityClass) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		String hql = "from " + entityClass.getName() + " as model where model." + propertyName + " = ?";
		return getSession().createQuery(hql).setParameter(0, value).list();
	}


	@Override
	@SuppressWarnings("unchecked")
	public List getAll(Class entityClass) {
		String hql = "from " + entityClass.getName();
		return getSession().createQuery(hql).list();
	}


	@Override
	public boolean isExist(String propertyName, Object value, Class entityClass) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		Object object = get(propertyName, value, entityClass);
		return (object != null);
	}


	@Override
	@SuppressWarnings("unchecked")
	public Serializable save(Serializable object) {
		Assert.notNull(object, "object is required");
		return getSession().save(object);
	}


	@Override
	public void update(Serializable object) {
		Assert.notNull(object, "object is required");
		getSession().update(object);
	}


	@Override
	public void delete(Serializable object) {
		Assert.notNull(object, "object is required");
		getSession().delete(object);
	}


	@Override
	public void delete(Serializable id, Class entityClass) {
		Assert.notNull(id, "id is required");
		Object object = load(id, entityClass);
		getSession().delete(object);
	}


	@Override
	public void delete(Serializable[] ids, Class entityClass) {
		Assert.notEmpty(ids, "ids must not be empty");
		for (Serializable id : ids) {
			Object entity = load(id,entityClass);
			getSession().delete(entity);
		}
	}


	@Override
	public void flush() {
		getSession().flush();
	}


	@Override
	public void clear() {
		getSession().clear();
	}


	@Override
	public void evict(Object object) {
		Assert.notNull(object, "object is required");
		getSession().evict(object);
	}

}
